//
// Created by Suzhen on 2016/12/17.
//

#ifndef ORIONV2_ASYNCEVENTGENERATORGROUP_H
#define ORIONV2_ASYNCEVENTGENERATORGROUP_H

#include "Orion.h"
#include "FutureAdapt.hpp"

ORION_V2_NAMESPACE_BEGIN

        //该类不是ThreadSafe的
        class AsyncEventGeneratorGroup {

        public:
            enum AsyncEventGeneratorGroupStatus {
                INIT,
                PREPARE_RUN,
                RUNNING,
                STOPPING,
                STOPPED
            };

            ~AsyncEventGeneratorGroup();

            //用户自定义Server生成器
            explicit AsyncEventGeneratorGroup(std::size_t clusterInitNum);

            //用户自定义Server生成器,注意生成的Server均被ServerCluster管理
            explicit AsyncEventGeneratorGroup(
                    std::function<ORION_V2::AsyncEventGenerator *(std::size_t)> serverGen);

            //Cluster会均衡的将负载平摊在每个Server上
            ORION_V2::AsyncEventGenerator *getLoadBalanceGenerator();

            //用户获取指定的 EventGenerator
            ORION_V2::AsyncEventGenerator *getAsyncEventGeneratorWithCustomRule(std::function<std::size_t()> f);

            //获取指定索引的 EventGenerator
            ORION_V2::AsyncEventGenerator *getAsyncEventGeneratorAt(std::size_t idx);

            /**
             * 异步启动
             * 当stop被调用,会被立即打断
             * 托管在Group中的所有EventGenerator被完整关闭,
             * @return future<bool>
             */
            Future<bool> run();

            /**
             * 异步关闭,
             * 会打断run的wait状态
             * 可以在run.then()中执行一些清理操作
             * @return  future
             */
            Future<bool> stop();

            /**
             * group 完全关闭的future
             * @return future
             */
            Future<bool> stopFuture();


            /**
             * 获取Group当前的状态
             * @return AsyncEventGeneratorGroupStatus
             */
            AsyncEventGeneratorGroupStatus getCurrentGroupStatus() const;


        private:
            std::vector<AsyncEventGenerator *> serverVec_;
            std::size_t lbFlag_{0};
            Promise<bool> runPromise_{};
            Promise<bool> closePromise_{};
            AsyncEventGeneratorGroupStatus status_{INIT};
            std::mutex internalLock_{};
        };

ORION_V2_NAMESPACE_END

#endif //ORIONV2_ASYNCEVENTGENERATORGROUP_H
